package ai.bruteForceSearch;

import java.util.*;

import search.Search;
import hexgame.GameLogic;
import hexgame.GameState;
import hexgame.HexMove;
import hexgame.HexPlayer;
import hexgame.Player;

public class BruteForceSearchAIPlayer extends Player {
	GameState gameState;
	HexMove firstMove = null;
	HexMove latestMove = null;

	public BruteForceSearchAIPlayer(GameState gameState) {
		this.gameState = gameState;
	}

	@Override
	public boolean isConnected() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public HexMove getMove() {
		HexMove move = null;
		if (firstMove == null) {
			this.makeFirstMove();
			move = firstMove;
		} else {
			HexMove[] path = findMostEfficientPath(latestMove);
			if(path == null || path.length == 0) {
				move = new HexMove(this.randInt(), this.randInt(), HexPlayer.RED_LOCAL);
				while(!GameLogic.isValidMove(gameState, move)) {
					move = new HexMove(this.randInt(), this.randInt(), HexPlayer.RED_LOCAL);
				}
			} else {
				move = new HexMove(path[0].getX(), path[0].getY(), HexPlayer.RED_LOCAL);
			}
		}
		latestMove = move;
		return move;
	}

	@Override
	public void showMove(HexMove move) {
		// TODO Auto-generated method stub

	}

	@Override
	public void gameOver(boolean didWin) {
		// TODO Auto-generated method stub

	}

	@Override
	public void sendErrorMessage(String message) {
		// TODO Auto-generated method stub

	}

	private void makeFirstMove() {
		if (gameState.getHexState(0, gameState.getBoardSize() / 2) == HexPlayer.NONE) {
			firstMove = new HexMove(0, gameState.getBoardSize() / 2, HexPlayer.RED_LOCAL);
		} else {
			firstMove = new HexMove(0, gameState.getBoardSize() / 2 + 1, HexPlayer.RED_LOCAL);
		}
	}

	private HexMove[] findMostEfficientPath(HexMove latest) {

		ArrayList<HexMove[]> possiblePaths = new ArrayList<HexMove[]>();
		Collection<HexMove> possibleMoves = GameLogic.getConnectingHexagons(new HexMove(latest.getX(), latest.getY(), HexPlayer.NONE), gameState);
		HexMove[] currentPath = null;
		HexMove[] shortestPath = null;

		for (HexMove move : possibleMoves) {
			currentPath = Search.shortestPathToEdge(move, gameState, true);
			if (currentPath != null) {
				possiblePaths.add(currentPath);
			}
		}

		if (possiblePaths.size() > 0) {
			shortestPath = possiblePaths.get(0);
			for (HexMove[] path : possiblePaths) {
				if (path.length < shortestPath.length) {
					shortestPath = path;
				}
			}
		} else {
			shortestPath = retracePathToPossibleMove(latest);
		}
		return shortestPath;
	}

	private HexMove[] retracePathToPossibleMove(HexMove latest) {

		Collection<HexMove> localFields = GameLogic.getConnectingHexagons(new HexMove(latest.getX(), latest.getY(), HexPlayer.RED_LOCAL), gameState);
		HexMove[] shortest = null;
		int distance = Integer.MAX_VALUE;
		for (HexMove hexMove : localFields) {
			Collection<HexMove> moves = GameLogic.getConnectingHexagons(new HexMove(hexMove.getX(), hexMove.getY(), HexPlayer.NONE), gameState);
			for (HexMove hexMove2 : moves) {
				HexMove[] path = Search.shortestPathToEdge(hexMove2, gameState, true);
				if (path != null) {
					if (path.length < distance) {
						shortest = path;
					}
				}
			}
		}
		if (shortest == null) {
			HexMove[] currentPath = null;
			for (int i = 0; i < gameState.getBoardSize(); i++) {
				currentPath = Search.shortestPathToEdge(new HexMove(0, i, HexPlayer.NONE), gameState, true);
				if (currentPath != null) {
				if (shortest == null) {
					shortest= currentPath;
				} else if (currentPath.length < shortest.length) {
					shortest = currentPath;
				}
				}
			}
		}
		return shortest;
	}
	
	public int randInt() {
		Random rand = new Random();
		return rand.nextInt(gameState.getBoardSize() + 1);
	}

}
